package com.xz.xzutils.module.xzmybatislogplus.dto;

import com.intellij.openapi.util.Key;
import lombok.Data;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author DONG.WANG17@HAND-CHINA.COM
 * @since 2025-02-16 19:52
 */
@Data
public class SocketPort {
    public static final Key<SocketPort> SOCKET_PORT_ENTITY = Key.create("SOCKET_PORT_ENTITY");
    public static final Key<Integer> SOCKET_PORT = Key.create("SOCKET_PORT");
    private Integer maxPort;
    private Integer minPort;
    private Set<Integer> usedPorts;
    public void addUsedPort(int port) {
        if(usedPorts == null){
            usedPorts = new HashSet<>();
        }
        usedPorts.add(port);
    }
    public int getRandomPort(){
        if (minPort == null || maxPort == null) {
            throw new IllegalStateException("必须先配置端口范围");
        }
        if (usedPorts == null) {
            usedPorts = new HashSet<>();
        }

        int portRange = maxPort - minPort + 1;
        if (usedPorts.size() >= portRange) {
            throw new IllegalStateException("没有可用端口");
        }

        int randomPort;
        do {
            randomPort = ThreadLocalRandom.current().nextInt(minPort, maxPort + 1);
            // 检测端口是否被系统占用
            try (ServerSocket socket = new ServerSocket(randomPort)) {
                socket.setReuseAddress(true);
            } catch (IOException e) {
                addUsedPort(randomPort); // 记录被系统占用的端口
            }
        } while (usedPorts.contains(randomPort));

        usedPorts.add(randomPort);
        return randomPort;
    }
}
